package com.ssy.lingxi.contract.esign.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.contract.esign.EsignProperties;
import com.ssy.lingxi.contract.esign.constant.RequestMethod;
import com.ssy.lingxi.contract.esign.exception.EsignError;
import com.ssy.lingxi.contract.esign.exception.EsignException;
import com.ssy.lingxi.contract.esign.request.FileUploadCreateRequest;
import com.ssy.lingxi.contract.esign.response.FileDetailResponse;
import com.ssy.lingxi.contract.esign.response.FileStatusResponse;
import com.ssy.lingxi.contract.esign.response.FileUploadCreateResponse;

import java.util.HashMap;
import java.util.Map;

/**
 * 文件模板API
 * @author yzc
 * @version 2.0.0
 * @date 2020/8/26
 */
public class FileTemplate {

    private final AuthToken authToken;
    private final EsignProperties properties;

    public FileTemplate(AuthToken authToken, EsignProperties properties) {
        this.authToken = authToken;
        this.properties = properties;
    }

    //=============================上传方式创建文件=============================

    /**
     * 通过上传方式创建文件
     */
    public FileUploadCreateResponse fileUploadCreate(FileUploadCreateRequest request) throws EsignException {
        String resourcePath = "/v1/files/getUploadUrl";
        RequestMethod method = RequestMethod.POST;

        Map<String, Object> paramMap = BeanUtil.beanToMap(request);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, FileUploadCreateResponse.class);
    }


    //=============================公共接口=============================

    /**
     * 查询文件状态
     */
    public FileStatusResponse fileStatus(String fileId) throws EsignException {
        String resourcePath = "/v1/files/{fileId}/status";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("fileId", fileId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, FileStatusResponse.class);
    }

    /**
     * 查询文件详情/下载文件
     */
    public FileDetailResponse fileDetail(String fileId) throws EsignException {
        String resourcePath = "/v1/files/{fileId}";
        RequestMethod method = RequestMethod.GET;

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("fileId", fileId);

        EsignRequest esignRequest = new EsignRequest(method, resourcePath, paramMap, authToken, properties);
        String execute = EsignResource.execute(esignRequest);

        return JSONUtil.toBean(execute, FileDetailResponse.class);
    }

    /**
     * 文件流上传
     */
    public void fileUpload(String uploadUrl, String md5Base64, byte[] fileBytes) throws EsignException {
        fileUpload(uploadUrl, md5Base64, fileBytes, "application/pdf");
    }

    /**
     * 文件流上传
     */
    public void fileUpload(String uploadUrl, String md5Base64, byte[] fileBytes, String contentType) throws EsignException {
        String result = HttpRequest.put(uploadUrl)
                .header("Content-MD5", md5Base64)
                .header("Content-Type", contentType)
                .body(fileBytes)
                .execute()
                .body();

        // 检查调用结果
        if (!JSONUtil.isJson(result)) {
            throw new EsignException(EsignError.builder().errMsg("json格式异常").json(result).build());
        }

        JSONObject jsonObject = JSONUtil.parseObj(result);

        if (!"0".equals(jsonObject.getStr("errCode"))) {
            throw new EsignException(EsignError.builder().errCode(jsonObject.getInt("errCode")).errMsg(jsonObject.getStr("msg")).json(result).build());
        }
    }

}